home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9212.ZIP / splay.asc < prev    next >
Text File  |  1992-11-30  |  6KB  |  270 lines

  1. _SPLAY TREES_
  2. by Dean Clark
  3.  
  4. [LISTING ONE]
  5.  
  6. void zig_left(TREENODE *t)
  7. {
  8.     TREENODE    *p, *r;
  9.     p = t->parent;
  10.     r = t->right;
  11.     t->right = p;
  12.     if (r) {
  13.         r->parent = p;
  14.         }
  15.     p->left = r;
  16.     p->parent = t;
  17. }
  18. void zig_right(TREENODE *t)
  19. {
  20.     TREENODE    *p, *l;
  21.     l = t->left;
  22.     p = t->parent;
  23.     p->right = t;
  24.     if (l) {
  25.         l->parent = t;
  26.     }
  27.     p->right = l;
  28.     p->parent = t;
  29. }
  30. void zig_zig_left(TREENODE *t)
  31. {
  32.     TREENODE    *p, *pr, *g, *r, *gp;
  33.     p = t->parent;
  34.     g = p->parent;
  35.     gp = g->parent;
  36.     r = t->right;
  37.     pr = p->right;
  38.     p->right = g;
  39.     g->left = pr;
  40.     t->parent = gp;
  41.     t->right = p;
  42.     p->left = r;
  43.     if (r) {
  44.         r->parent = p;
  45.     }
  46.     if (pr) {
  47.         pr->parent = g;
  48.     }
  49.     if (gp) {
  50.         if (gp->left == g) {
  51.             gp->left = t;
  52.         }
  53.         else {
  54.             gp->right = t;
  55.         }
  56.     }
  57. }
  58. void zig_zig_right(TREENODE *t)
  59. {
  60.     TREENODE    *p, *pl, *g, *l, *gp;
  61.     p = t->parent;
  62.     g = p->parent;
  63.     gp = g->parent;
  64.     l = t->left;
  65.     pl = p->left;
  66.     p->left = g;
  67.     g->right = pl;
  68.     t->parent = gp;
  69.     t->left = p;
  70.     p->right = l;
  71.     if (l) {
  72.         l->parent = p;
  73.     }
  74.     if (pl) {
  75.         pl->parent = g;
  76.     }
  77.     if (gp) {
  78.         if (gp->left == g) {
  79.             gp->left = t;
  80.         }
  81.         else {
  82.             gp->right = t;
  83.         }
  84.     }
  85. }
  86. void zig_zag_left(TREENODE *t)
  87. {
  88.     TREENODE    *p, *gp, *ggp, *l, *r;
  89.     p = t->parent;
  90.     gp = p->parent;
  91.     ggp = gp->parent;
  92.     l = t->left;
  93.     r = t->right;
  94.     t->parent = ggp;
  95.     t->left = p;
  96.     t->right = gp;
  97.     gp->parent = t;
  98.     p->parent = t;
  99.     p->right = l;
  100.     gp->left = r;
  101.     if (l) {
  102.         l->parent = p;
  103.     }
  104.     if (r) {
  105.         r->parent = gp;
  106.     }
  107.     if (ggp) {
  108.         if (ggp->left == gp) {
  109.             ggp->left = t;
  110.         }
  111.         else {
  112.             ggp->right = t;
  113.         }
  114.     }
  115. }
  116. void zig_zag_right(TREENODE *t)
  117. {
  118.     TREENODE    *p, *gp, *ggp, *l, *r;
  119.     p = t->parent;
  120.     gp = p->parent;
  121.     ggp = gp->parent;
  122.     l = t->left;
  123.     r = t->right;
  124.     t->left = gp;
  125.     t->right = p;
  126.     t->parent = ggp;
  127.     p->parent = t;
  128.     gp->parent = t;
  129.     gp->right = l;
  130.     p->left = r;
  131.     if (l) {
  132.         l->parent = gp;
  133.     }
  134.     if (r) {
  135.         r->parent = p;
  136.     }
  137.     if (ggp) {
  138.         if (ggp->left == gp) {
  139.             ggp->left = t;
  140.         }
  141.         else {
  142.             ggp->right = t;
  143.         }
  144.     }
  145. }
  146.  
  147.  
  148. [LISTING TWO]
  149.  
  150. /* Splay functions 
  151. **  Assumptions: Tree is pointed to by global variable T, 
  152. **   type KEYTYPE
  153. **     External function Compare_Key(KEYTYPE k1, KEYTYPE k2) returns
  154. **         0 if the two keys are equal, -1 if first key is less than
  155. **         second, 1 if first is greater than second
  156. **     External rotation functions from listing 1
  157. */
  158.  
  159. Splay(KEYTYPE k)
  160. {
  161.     int gle;
  162.     /* Assume global tree T.  Traverse T looking for key.  Compare_Key()
  163.     ** returns 0 if the two keys are equal, -1 if the first is less than
  164.     ** the second, 1 if first is greater than the second */
  165.     while ((gle = Compare_Key(T->key,k)) != 0) {
  166.         if (gle > 0) {
  167.             if (T->left) {
  168.                 T = T->left;
  169.             }
  170.             else break;
  171.         }
  172.         else {
  173.             if (T->right) {
  174.                 T = T->right;
  175.             }
  176.             else break;
  177.         }
  178.     }
  179.     /* T now points to the node containing the key k, or to the inorder
  180.     ** successor or predecessor to k. We don't really care which at
  181.     ** this point. T will be root when its parent pointer points to itself */
  182.     while (T->parent != T) {
  183.         if (T->parent->parent) {
  184.             /* zig-zig or zig-zag*/
  185.             if (T->parent->parent->left == T->parent) {
  186.                 if (T->parent->left == T) {
  187.                     zig_zig_left(T);
  188.                 }
  189.                 else {
  190.                     zig_zag_left(T);
  191.                 }
  192.             }
  193.             else {
  194.                 if (T->parent->right == T) {
  195.                     zig_zig_right(T);
  196.                 }
  197.                 else {
  198.                     zig_zag_right(T);
  199.                 }
  200.             }
  201.         }
  202.         else {
  203.             /* zig */
  204.             if (T->parent->left == T) {
  205.                 zig_left(T);
  206.             }
  207.             else {
  208.                 zig_right(T);
  209.             }
  210.         }
  211.     }
  212. }
  213.  
  214.  
  215.  
  216. [LISTING THREE]
  217.  
  218. /* Splay Tree Standard Operations -- Find, Delete and Insert functions for 
  219. **   splay trees. Assumptions:
  220. **     Tree is pointed to by global variable T, type KEYTYPE
  221. **     External function Compare_Key(KEYTYPE k1, KEYTYPE k2) returns
  222. **         0 if the two keys are equal, -1 if first key is less than
  223. **         second, 1 if first is greater than second
  224. **     External function Destroy_Key(KEYTYPE k) that recovers memory
  225. **         used by a key
  226. **     Special KEYTYPE variable ERROR_KEY used as an error sentinel
  227. */
  228.  
  229. KEYTYPE Find(KEYTYPE k)
  230. {
  231.     Splay(k);
  232.     /* If k was in the tree it's now the root node */
  233.     if (T->key == k) {
  234.         return (T->key);
  235.     }
  236.     else {
  237.         return (ERROR_KEY);
  238.     }
  239. }
  240. void Delete(KEYTYPE k)
  241. {
  242.     TREENODE    *l, *r;
  243.     /* Bring target node to the root */
  244.     Splay(k);
  245.     /* Make sure key was in the tree... */
  246.     if (Compare_Key(T->key, k) == 0) {
  247.         /* Detach the node and dispose of it */
  248.         l = T->left;
  249.         r = T->right;
  250.         Destroy_Node(T);
  251.         /* Splay left subtree to find the new root of tree (see text) */
  252.         T = l;
  253.         Splay(k);
  254.         /* Root and left subtree are fine now, just attach right subtree */
  255.         T->right = r;
  256.     }
  257. }
  258. void Insert(KEYTYPE k)
  259. {
  260.     TREENODE    *x;
  261.     /* Insert the new node into the tree */
  262.     Attach_Node(k);
  263.     /* Now Splay to bring the new node to root. This is somewhat inefficient 
  264.     ** because Splay searches the tree all over again. */
  265.     Splay(k);
  266. }
  267.  
  268.  
  269.  
  270.